package cn.lds.j368.dsbank.advice;

import cn.lds.j368.dsbank.annotation.SysLogAnnotation;
import cn.lds.j368.dsbank.domain.Employee;
import cn.lds.j368.dsbank.domain.SysLog;
import cn.lds.j368.dsbank.domain.SysLogParams;
import cn.lds.j368.dsbank.service.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

@Aspect
@Component
public class SysLogAdvice {

    @Autowired
    private SysLogService sysLogService;

    private Logger log = LoggerFactory.getLogger(SysLogAdvice.class);

    //定义切入点表达式 扫描项目中所有有@SysLogAnnotation注解的类或者方法
    @Pointcut("@annotation(cn.lds.j368.dsbank.annotation.SysLogAnnotation)")
    public void operLogPontCut(){

    }
//
    @AfterReturning(value = "operLogPontCut()")
    public void saveOperLog(JoinPoint joinPoint){

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        //获取HttpRequest对象
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

        //定义日志对象
        SysLog sysLog = new SysLog();

        //获取客户端IP地址
        String ipAddress = request.getRemoteAddr();
        //获取访问方法的方法前面
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获取访问的方法的方法对象
        Method method = methodSignature.getMethod();
        //获取方法的日志注解
        SysLogAnnotation sysLogAnnotation = method.getAnnotation(SysLogAnnotation.class);

        Employee loginEmployee = (Employee) SecurityContextHolder.getContext().getAuthentication().getPrincipal();



//        log.info("登录信息{}",loginEmployee);

        log.info(loginEmployee.getUsername());
        log.info(ipAddress);
        log.info(sysLogAnnotation.operUrl());
        log.info(sysLogAnnotation.operModul());
        log.info(sysLogAnnotation.operType());
        log.info(sysLogAnnotation.operDesc());

        sysLog.setEmpUsername(loginEmployee.getEmpUsername());
        sysLog.setOperatorTime(new Date());
        sysLog.setModel(sysLogAnnotation.operModul());
        sysLog.setDescripation(sysLogAnnotation.operDesc());
        sysLog.setVisitUrl(sysLogAnnotation.operUrl());
        sysLog.setType(sysLogAnnotation.operType());
        sysLog.setMethodName(methodSignature.getName());
        sysLog.setIpAddress(ipAddress);

        log.info("sysLog：{}",sysLog);

        //获取请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();

        List<SysLogParams> sysLogParams = this.converParamMap(parameterMap);

        //存储日志
        sysLogService.addSysLog(sysLog,sysLogParams);

//        log.info("aop日志工作开始运行");
    }

    public List<SysLogParams> converParamMap(Map<String,String[]> paramMap){

        log.info("整合参数方法执行……");

        List<SysLogParams> sysLogParams = new ArrayList<>();

        Set<String> strings = paramMap.keySet();

        strings.forEach(k->{
            sysLogParams.add(new SysLogParams(k,paramMap.get(k)[0]));
        });


        return sysLogParams;
    }
}
